package com.itmuch.box.service.content;

import java.math.BigInteger;
import java.util.List;
import java.util.Map;
import java.util.Set;

import javax.persistence.EntityManager;
import javax.persistence.Query;

import org.apache.commons.collections.CollectionUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.data.jpa.domain.Specification;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import com.itmuch.box.core.PageNative;
import com.itmuch.box.core.base.BaseService;
import com.itmuch.box.core.dynamicSpec.jpa.DynamicSpecifications;
import com.itmuch.box.core.dynamicSpec.jpa.PageVo;
import com.itmuch.box.core.dynamicSpec.jpa.SearchFilter;
import com.itmuch.box.dao.content.ContentRepository;
import com.itmuch.box.domain.content.entity.Content;
import com.itmuch.box.domain.content.vo.ContentDirectiveVo;
import com.itmuch.box.domain.content.vo.ContentSearchVo;
import com.itmuch.box.domain.content.vo.ContentVo;
import com.itmuch.box.domain.tag.entity.Tag;
import com.itmuch.box.service.tag.TagService;

@Service
@Transactional
public class ContentService extends BaseService<ContentRepository, Content> {
    @Autowired
    private TagService tagService;

    public Page<Content> findByConditionPaged(ContentSearchVo condition, Pageable pageable) {

        Map<String, Object> map = Maps.newHashMap();
        map.put("EQ_categoryId", condition.getCategoryId());
        map.put("LIKE_title", condition.getTitle());
        map.put("GTE_issueTime", condition.getStartTime());
        map.put("LTE_issueTime", condition.getEndTime());

        Map<String, SearchFilter> parse = SearchFilter.parse(map);
        Specification<ContentSearchVo> specification = DynamicSpecifications.bySearchFilter(parse.values(), ContentSearchVo.class);
        Page<Content> page = this.dao.findAll(specification, pageable);

        return page;
    }

    public Page<Content> findByMemberIdAndModelId(Integer memberId, Integer modelId, PageRequest pageRequest) {
        return this.dao.findByMemberIdAndModelId(memberId, modelId, pageRequest);
    }

    @Autowired
    private EntityManager entityManager;

    @SuppressWarnings("unchecked")
    public PageNative<ContentVo> selectContentVoByConditonPaged(ContentDirectiveVo condition, PageVo pageVo) {
        Integer pageNo = pageVo.getPage();
        Integer pageSize = pageVo.getRows();
        int start = (pageNo - 1) * pageSize;
        String sql = "SELECT DISTINCT a.* FROM f_content a LEFT JOIN mid_content_recomend b ON a.id = b.content_id where 1=1 ";

        Integer categoryId = condition.getCategoryId();
        Boolean coverFlag = condition.getCoverFlag();
        Integer modelId = condition.getModelId();
        Integer recomendId = condition.getRecomendId();
        Set<Integer> sortIds = condition.getSortIds();
        if (categoryId != null) {
            sql += " and a.category_id = " + categoryId;
        }
        if (coverFlag != null && coverFlag) {
            sql += " and a.cover !=''";
        }
        if (modelId != null) {
            sql += " and a.model_id = " + modelId;
        }
        if (recomendId != null) {
            sql += " and b.recomend_id = " + recomendId;
        }
        if (CollectionUtils.isNotEmpty(sortIds)) {
            sql += " and a.sort_id in (" + sortIds.toString().replace("[", "").replace("]", "") + ")";
        }

        Query query = this.entityManager.createNativeQuery(sql, Content.class);
        query.setFirstResult(start);
        query.setMaxResults(pageSize);

        List<Content> resultList = query.getResultList();

        if (CollectionUtils.isNotEmpty(resultList)) {
            List<ContentVo> voList = Lists.newArrayList();
            for (Content content : resultList) {
                ContentVo contentVo = new ContentVo();
                contentVo.setContent(content);

                Set<Tag> tags = this.tagService.findByContentId(content.getId());
                contentVo.setTags(tags);
                voList.add(contentVo);

            }

            String countSql = "select COUNT(1) from (" + sql + ")temp";
            Query query2 = this.entityManager.createNativeQuery(countSql);
            BigInteger singleResult = (BigInteger) query2.getSingleResult();

            PageNative<ContentVo> p = new PageNative<ContentVo>(voList, singleResult.intValue(), pageVo.getPage(), pageVo.getRows());
            return p;
        } else {
            List<ContentVo> voList = Lists.newArrayList();
            return new PageNative<ContentVo>(voList, 0, pageVo.getPage(), pageVo.getRows());
        }

    }
}
